home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
machserver
/
1.098
/
main
/
sun3.md
/
mainInit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-08
|
12KB
|
467 lines
/*
* main.c --
*
* The main program for Sprite: initializes modules and creates
* system processes. Also creates a process to run the Init program.
*
* Copyright 1986 Regents of the University of California
* All rights reserved.
*/
#ifndef lint
static char rcsid[] = "$Header: /sprite/src/kernel/main/sun3.md/RCS/mainInit.c,v 1.9 91/04/08 12:08:02 mgbaker Exp $ SPRITE (Berkeley)";
#endif /* !lint */
#include <sprite.h>
#include <dbg.h>
#include <dev.h>
#include <net.h>
#include <fs.h>
#include <fsutil.h>
#include <proc.h>
#include <prof.h>
#include <recov.h>
#include <rpc.h>
#include <sched.h>
#include <sig.h>
#include <sync.h>
#include <sys.h>
#include <timer.h>
#include <vm.h>
#include <machMon.h>
#include <devAddrs.h>
#include <mach.h>
#include <main.h>
#include <stdio.h>
#include <bstring.h>
#include <string.h>
#include <dump.h>
static void Init _ARGS_((void));
/*
* Pathname of the Init program.
*/
#define INIT "cmds/initsprite"
int main_PrintInitRoutines = FALSE; /* print out each routine as
* it's called? */
int main_PanicOK = 0; /* Set to 1 if it's OK to panic. */
/*
*----------------------------------------------------------------------
*
* main --
*
* All kernel modules are initialized by calling their *_Init()
* routines. In addition, kernel processes are created to
* handle virtual memory and rpc-specific stuff. The last process
* created runs the `init' program.
*
* Results:
* None.
*
* Side effects:
* The whole system is initialized.
*
*----------------------------------------------------------------------
*/
void
main()
{
Proc_PID pid;
int i;
/*
* Initialize variables specific to a given kernel.
* IMPORTANT: Only variable assignments and nothing else can be
* done in this routine.
*/
Main_InitVars();
/*
* Initialize machine dependent info. MUST BE CALLED HERE!!!.
*/
Mach_Init();
Sync_Init();
/*
* Initialize the debugger.
*/
Dbg_Init();
/*
* Initialize the system module, particularly the fact that there is an
* implicit DISABLE_INTR on every processor.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Sys_Init().\n");
}
Sys_Init();
/*
* Now allow memory to be allocated by the "Vm_BootAlloc" call. Memory
* can be allocated by this method until "Vm_Init" is called. After this
* then the normal memory allocator must be used.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Vm_BootInit().\n");
}
Vm_BootInit();
/*
* Initialize all devices.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Dev_Init().\n");
}
Dev_Init();
/*
* Initialize the mappings of keys to call dump routines.
* Must be after Dev_Init.
*/
if (main_DoDumpInit) {
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Dump_Init().\n");
}
Dump_Init();
}
/*
* Initialize the timer, signal, process, scheduling and synchronization
* modules' data structures.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Proc_Init().\n");
}
Proc_Init();
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Sync_LockStatInit().\n");
}
Sync_LockStatInit();
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Timer_Init().\n");
}
Timer_Init();
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Sig_Init().\n");
}
Sig_Init();
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Sched_Init().\n");
}
Sched_Init();
/*
* Sys_Printfs are not allowed before this point.
*/
main_PanicOK++;
printf("Sprite kernel: %s\n", SpriteVersion());
/*
* Set up bins for the memory allocator.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Fs_Bin\n");
}
Fs_Bin();
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Net_Bin\n");
}
Net_Bin();
/*
* Initialize virtual memory. After this point must use the normal
* memory allocator to allocate memory. If you use Vm_BootAlloc then
* will get a panic into the debugger.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Vm_Init\n");
}
Vm_Init();
/*
* malloc can be called from this point on.
*/
/*
* Initialize the main process. Must be called before any new
* processes are created.
* Dependencies: Proc_InitTable, Sched_Init, Vm_Init, Mem_Init
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Proc_InitMainProc\n");
}
Proc_InitMainProc();
/*
* Initialize the network and the routes. It would be nice if we
* could call Net_Init earlier so that we can use the debugger earlier
* but we must call Vm_Init first. VM could be changed so that we
* could move the call earlier however.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Net_Init\n");
}
Net_Init();
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Net_RouteInit\n");
}
Net_RouteInit();
/*
* Enable server process manager.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Proc_ServerInit\n");
}
Proc_ServerInit();
/*
* Initialize the recovery module. Do before Rpc and after Vm_Init.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Recov_Init\n");
}
Recov_Init();
/*
* Initialize the data structures for the Rpc system. This uses
* Vm_RawAlloc to so it must be called after Vm_Init.
* Dependencies: Timer_Init, Vm_Init, Net_Init, Recov_Init
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Rpc_Init\n");
}
Rpc_Init();
/*
* Configure devices that may or may not exist. This needs to be
* done after Proc_InitMainProc because the initialization routines
* use SetJump which uses the proc table entry for the main process.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Dev_Config\n");
}
Dev_Config();
/*
* Initialize profiling after the timer and vm stuff is set up.
* Dependencies: Timer_Init, Vm_Init
*/
if (main_DoProf) {
Prof_Init();
}
/*
* Allow interrupts from now on.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Enabling interrupts\n");
}
ENABLE_INTR();
if (main_Debug) {
DBG_CALL;
}
/*
* Sleep for a few seconds to calibrate the idle time ticks.
*/
Sched_TimeTicks();
/*
* Start profiling, if desired.
*/
if (main_DoProf) {
(void) Prof_Start();
}
/*
* Do an initial RPC to get a boot timestamp. This allows
* servers to detect when we crash and reboot. This will set the
* system clock too, although rdate is usually done from user level later.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Call Rpc_Start\n");
}
Rpc_Start();
/*
* Initialize the file system.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Call Fs_Init\n");
}
Fs_Init();
/*
* Before starting up any more processes get a current directory
* for the main process. Subsequent new procs will inherit it.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Call Fs_ProcInit\n");
}
Fs_ProcInit();
if (main_PrintInitRoutines) {
Mach_MonPrintf("Bunch of call funcs\n");
}
/*
* Start the clock daemon and the routine that opens up the swap directory.
*/
Proc_CallFunc(Vm_Clock, (ClientData) NIL, 0);
Proc_CallFunc(Vm_OpenSwapDirectory, (ClientData) NIL, 0);
/*
* Start the process that synchronizes the filesystem caches
* with the data kept on disk.
*/
Proc_CallFunc(Fsutil_SyncProc, (ClientData) NIL, 0);
/*
* Create a few RPC server processes and the Rpc_Daemon process which
* will create more server processes if needed.
*/
if (main_NumRpcServers > 0) {
for (i=0 ; i<main_NumRpcServers ; i++) {
(void) Rpc_CreateServer((int *) &pid);
}
}
(void) Proc_NewProc((Address) Rpc_Daemon, PROC_KERNEL, FALSE, &pid,
"Rpc_Daemon");
if (main_PrintInitRoutines) {
Mach_MonPrintf("Creating Proc server procs\n");
}
/*
* Create processes to execute functions.
*/
for (i = 0; i < proc_NumServers; i++) {
(void) Proc_NewProc((Address) Proc_ServerProc, PROC_KERNEL, FALSE,
&pid, "Proc_ServerProc");
}
/*
* Create a recovery process to monitor other hosts. Can't use
* Proc_CallFunc's to do this because they can be used up waiting
* for page faults against down servers. (Alternatively the VM
* code could be fixed up to retry page faults later instead of
* letting the Proc_ServerProc wait for recovery.)
*/
(void) Proc_NewProc((Address) Recov_Proc, PROC_KERNEL, FALSE, &pid,
"Recov_Proc");
/*
* Set up process migration recovery management.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Proc_MigInit\n");
}
Proc_MigInit();
/*
* Call the routine to start test kernel processes.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Calling Main_HookRoutine\n");
}
Main_HookRoutine();
/*
* Print out the amount of memory used.
*/
printf("MEMORY %d bytes allocated for kernel\n",
vmMemEnd - mach_KernStart);
/*
* Start up the first user process.
*/
if (main_PrintInitRoutines) {
Mach_MonPrintf("Creating Init\n");
}
(void) Proc_NewProc((Address) Init, PROC_KERNEL, FALSE, &pid, "Init");
(void) Sync_WaitTime(time_OneYear);
printf("Main exiting\n");
Proc_Exit(0);
}
/*
*----------------------------------------------------------------------
*
* Init --
*
* This routine execs the init program.
*
* Results:
* This routine only returns an error if the exec failed.
*
* Side effects:
* The current process image is overlayed by the init process.
*
*----------------------------------------------------------------------
*/
static void
Init()
{
char *initArgs[10];
ReturnStatus status;
char argBuffer[100];
int argc;
Fs_Stream *dummy;
char bootCommand[103];
char *ptr;
int i;
int argLength;
if (main_PrintInitRoutines) {
Mach_MonPrintf("In Init\n");
}
bzero(bootCommand, 103);
argc = Mach_GetBootArgs(8, 100, &(initArgs[2]), argBuffer);
if (argc > 0) {
argLength = (((int) initArgs[argc+1]) + strlen(initArgs[argc+1]) +
1 - ((int) argBuffer));
} else {
argLength = 0;
}
if (argLength > 0) {
initArgs[1] = "-b";
ptr = bootCommand;
for (i = 0; i < argLength; i++) {
if (argBuffer[i] == '\0') {
*ptr++ = ' ';
} else {
*ptr++ = argBuffer[i];
}
}
bootCommand[argLength] = '\0';
initArgs[2] = bootCommand;
initArgs[argc + 2] = (char *) NIL;
} else {
initArgs[1] = (char *) NIL;
}
if (main_AltInit != 0) {
initArgs[0] = main_AltInit;
printf("Execing \"%s\"\n", initArgs[0]);
status = Proc_KernExec(initArgs[0], initArgs);
printf( "Init: Could not exec %s status %x.\n",
initArgs[0], status);
}
status = Fs_Open(INIT,FS_EXECUTE | FS_FOLLOW, FS_FILE, 0, &dummy);
if (status != SUCCESS) {
printf("Can't open %s <0x%x>\n", INIT,status);
}
initArgs[0] = INIT;
status = Proc_KernExec(initArgs[0], initArgs);
printf( "Init: Could not exec %s status %x.\n",
initArgs[0], status);
Proc_Exit(1);
}